package com.tbsoft.ehr.service.resume;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.util.Version;

import com.tbsoft.ehr.dao.index.IndexBuildTaskDao;
import com.tbsoft.ehr.dao.resume.ResumeDao;
import com.tbsoft.ehr.model.AttachFile;
import com.tbsoft.ehr.model.IndexBuildTask;
import com.tbsoft.ehr.model.Resume;

/**
 * @desc 简历Service
 * @author vastdream
 *
 */
public class ResumeServiceImpl implements ResumeService{
	private ThreadLocal<Integer> keyworkHintsCount = new ThreadLocal<Integer>();;
	private ResumeDao resumeDao;
	public void setResumeDao(ResumeDao resumeDao) {
		this.resumeDao = resumeDao;
	}
	public void saveResume(Resume resume , List<AttachFile> attachFileList)throws IOException{
		 resumeDao.save(resume);
		 resumeDao.saveOrUpdateAttachfile(attachFileList, resume.getId());
		 IndexBuildTask ibt = new IndexBuildTask();
		 ibt.setBusinessId(resume.getId());
		 ibt.setTaskType("resume");
		 ibt.setOperate("A");
		 indexBuildTaskDao.save(ibt);
	}
	@Override
	public List<Resume> getResumeList(Resume resume,int startIndex,int count) {
		if(resume.getKeyword() != null && !resume.getKeyword().isEmpty()){
			return getResumeListByIndex(resume, startIndex, count);
		}
		return resumeDao.getResumeList(resume,startIndex,count);
	}
	@Override
	public int getResumeCount(Resume resume) {
		if(resume.getKeyword() != null && !resume.getKeyword().isEmpty()){
			return keyworkHintsCount.get();
		}
		return resumeDao.getResumeCount(resume);
	}
	@Override
	public Resume getResumeById(String id) {
		return resumeDao.getResumeById(id);
	}
	@Override
	public void savrOrupdateResume(Resume resume, List<AttachFile> attachFileList) throws IOException {
		 resumeDao.saveOrUpdate(resume);
		 resumeDao.saveOrUpdateAttachfile(attachFileList, resume.getId());
		 IndexBuildTask ibt = new IndexBuildTask();
		 ibt.setBusinessId(resume.getId());
		 ibt.setTaskType("resume");
		 ibt.setOperate("U");
		 indexBuildTaskDao.save(ibt);
		 
	}
	@Override
	public void deleteResume(Resume resume) {
		resumeDao.logicDelete(Resume.class,resume.getId());
		IndexBuildTask ibt = new IndexBuildTask();
		 ibt.setBusinessId(resume.getId());
		 ibt.setTaskType("resume");
		 ibt.setOperate("D");
		 indexBuildTaskDao.save(ibt);
	}
	
	@Override
	public Resume getResumeByUserId(String userid) {
		return resumeDao.getResumeByUserId(userid);
	}
	
	@Override
	public void saveInterviewResult(Resume resume) {
		Resume tmpResume = resumeDao.getResumeById(resume.getId());
		tmpResume.setInterviewStatus(resume.getInterviewStatus());
		tmpResume.setInterviewComments(resume.getInterviewComments());
		tmpResume.setContactDate(resume.getContactDate());
		resumeDao.saveOrUpdate(tmpResume);
	}
	
	private IndexBuildTaskDao indexBuildTaskDao;
	public void setIndexBuildTaskDao(IndexBuildTaskDao indexBuildTaskDao) {
		this.indexBuildTaskDao = indexBuildTaskDao;
	}
	
	private IndexSearcher indexSearcher;
	public void setIndexSearcher(IndexSearcher indexSearcher) {
		this.indexSearcher = indexSearcher;
	}
	private Log log = LogFactory.getLog(getClass());
	public List<Resume> getResumeListByIndex(Resume resume,int startIndex,int count){
		BooleanQuery query = new BooleanQuery();
		if(resume.getName()!= null && !resume.getName().isEmpty()){
			Term term = new Term("name",resume.getName());
			query.add(new TermQuery(term), BooleanClause.Occur.MUST);
		}
		if(resume.getPost() != null && !resume.getPost().isEmpty()){
			Term term = new Term("post",resume.getPost());
			query.add(new TermQuery(term),BooleanClause.Occur.MUST);
		}
		if(resume.getEducationLevel() != null && !resume.getEducationLevel().isEmpty()){
			Term term = new Term("educationLevel",resume.getEducationLevel());
			query.add(new TermQuery(term),BooleanClause.Occur.MUST);
		}
		try {
			if(resume.getKeyword() != null && !resume.getKeyword().isEmpty()){
			
				QueryParser qp = new QueryParser(Version.LUCENE_34,"occupationalCharacteristics",ikAnalyzer);
				qp.setDefaultOperator(QueryParser.AND_OPERATOR);
				Query tquery1 = qp.parse(resume.getKeyword());
				query.add(tquery1, BooleanClause.Occur.SHOULD);
				
				QueryParser qp2 = new QueryParser(Version.LUCENE_34,"technicalExpertise",ikAnalyzer);
				qp2.setDefaultOperator(QueryParser.AND_OPERATOR);
				Query tquery2 = qp2.parse(resume.getKeyword());
				query.add(tquery2, BooleanClause.Occur.SHOULD);
				
				QueryParser qp3 = new QueryParser(Version.LUCENE_34,"selfEvaluation",ikAnalyzer);
				qp3.setDefaultOperator(QueryParser.AND_OPERATOR);
				Query tquery3 = qp3.parse(resume.getKeyword());
				query.add(tquery3, BooleanClause.Occur.SHOULD);
				
				QueryParser qp4 = new QueryParser(Version.LUCENE_34,"projectSummary",ikAnalyzer);
				qp4.setDefaultOperator(QueryParser.AND_OPERATOR);
				Query tquery4 = qp4.parse(resume.getKeyword());
				query.add(tquery4, BooleanClause.Occur.SHOULD);
				
				QueryParser qp5 = new QueryParser(Version.LUCENE_34,"jobDuties",ikAnalyzer);
				qp5.setDefaultOperator(QueryParser.AND_OPERATOR);
				Query tquery5 = qp5.parse(resume.getKeyword());
				query.add(tquery5, BooleanClause.Occur.SHOULD);
				
				QueryParser qp6 = new QueryParser(Version.LUCENE_34,"mainTechnical",ikAnalyzer);
				qp6.setDefaultOperator(QueryParser.AND_OPERATOR);
				Query tquery6 = qp6.parse(resume.getKeyword());
				query.add(tquery6, BooleanClause.Occur.SHOULD);
			}
			//更新查询最新的索引
			IndexReader readerNow = indexSearcher.getIndexReader();
			if(!readerNow.isCurrent()){
				indexSearcher = new IndexSearcher(IndexReader.openIfChanged(readerNow));
			}
			TopDocs topDocs = indexSearcher.search(query, 1000);
			log.info("命中:"+topDocs.totalHits);
			
			if(topDocs.totalHits == 0 ){
				keyworkHintsCount.set(0);
				return new ArrayList<Resume>();
			}
			ScoreDoc[] scoreDocs = topDocs.scoreDocs;
			Set<String> idSet = new HashSet<String>();
			for(int i=0;i<topDocs.totalHits;i++){
				Document targetDoc = indexSearcher.doc(scoreDocs[i].doc);
				idSet.add(targetDoc.get("ID"));
			}
			keyworkHintsCount.set(idSet.size());
			return resumeDao.getResumeByListId(idSet);
		} catch (Exception e) {
			log.error("search index exception:", e);
			return new ArrayList<Resume>();
		} 
	}
	private Analyzer ikAnalyzer;
	public void setIkAnalyzer(Analyzer ikAnalyzer) {
		this.ikAnalyzer = ikAnalyzer;
	}
}
